home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / hrtmon / src / file.s < prev    next >
Text File  |  1999-01-29  |  39KB  |  1,799 lines

  1.  
  2. ;HRTmon Amiga system monitor
  3. ;Copyright (C) 1991-1998 Alain Malek Alain.Malek@cryogen.com
  4. ;
  5. ;This program is free software; you can redistribute it and/or
  6. ;modify it under the terms of the GNU General Public License
  7. ;as published by the Free Software Foundation; either version 2
  8. ;of the License, or (at your option) any later version.
  9. ;
  10. ;This program is distributed in the hope that it will be useful,
  11. ;but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ;GNU General Public License for more details.
  14. ;
  15. ;You can find the full GNU GPL online at: http://www.gnu.org
  16.  
  17. ;file access routines
  18.  
  19. ;-----------------------------------------------------
  20. ;-------------- can open max 2 files -----------------
  21.  
  22. ;-> d1=ptr on filename (ended by a zero)
  23. ;-> d2=mode 0=oldfile,-1=newfile,1=oldfile or olddir (used to delete a dir)
  24. ;<- d0=ptr on file_handle
  25.  
  26. open_file    movem.l    d1-d7/a0-a4,-(a7)
  27.         st    disk_op
  28.         move.l    d2,d7            ;copy mode in d7
  29.         move.l    d1,d6            ;copy of full filename* in d6
  30.         lea.l    file_handle1,a1
  31.         tst.l    (a1)
  32.         beq.b    .okfree
  33.         lea.l    file_handle2,a1
  34.         tst.l    (a1)
  35.         beq.b    .okfree
  36.         moveq    #0,d0
  37.         bra.w    .error
  38.  
  39. .okfree        bsr    find_partition
  40.         tst.l    d0
  41.         beq.w    .error
  42.         move.l    d0,a3
  43.         move.l    d0,file_part(a1)
  44.         move.l    d2,file_parent(a1)
  45.         clr.l    file_seek(a1)
  46.         clr.l    file_extpos(a1)
  47.         sf    file_written(a1)
  48.         sf    file_dir(a1)
  49.  
  50.         bsr    copy_name        ;set BCPL name into filehandle
  51.  
  52.         move.l    part_device(a3),a2
  53.         lea.l    extension,a0
  54.         move.l    file_parent(a1),d0
  55.         move.l    d0,d3
  56.         bsr    read_fbuffer        ;read ROOT or PARENT
  57.         bsr    test_sum
  58.         beq.b    .oksum
  59.         moveq    #0,d0
  60.         bra.w    .error
  61. .oksum
  62.         tst.l    d7            ;oldfile or newfile ?
  63.         bpl.w    .oldfile
  64.  
  65. ;-------------- open new file --------------
  66.  
  67.         clr.l    file_size(a1)
  68.  
  69.         bsr    alloc_block        ;find block for file_header
  70.         bpl.b    .okhead
  71.         move.w    #DISKFULL_ERR,drive_err
  72.         moveq    #0,d0
  73.         bra.w    .error
  74. .okhead        move.l    d0,file_header(a1)
  75.         move.l    d0,file_extension(a1)
  76.         bsr    calc_hash
  77.         move.l    d3,d6            ;d6=place where to ins. in hash
  78.         sf    d5            ;signal for d6 found
  79. .next2        lea.l    extension,a0
  80.         move.l    (a0,d0.w),d0        ;find end of hash list
  81.         beq.b    .okfreeh
  82.         tst.b    d5            ;already found place where
  83.         bne.b    .foundins        ;to insert in hash list ?
  84.         cmp.l    file_header(a1),d0
  85.         bls.b    .foundins
  86.         st    d5
  87.         move.l    d3,d6            ;d6=place where to ins. in hash
  88. .foundins    move.l    d0,d3            ;d3=no of actual loaded block
  89.         bsr    read_fbuffer        ;read next in hash list
  90.         bsr    test_sum
  91.         beq.b    .oksum2
  92.         move.l    file_header(a1),d0
  93.         bsr    free_block
  94.         bsr    update_bitmap
  95.         moveq    #0,d0
  96.         bra.w    .error
  97. .oksum2        lea.l    108*4(a0),a0
  98.         bsr    cmp_filename        ;file already exists ?
  99.         bne.b    .different
  100.         move.l    file_header(a1),d0
  101.         bsr    free_block
  102.         bsr    update_bitmap
  103.         move.w    #FILEEXIST_ERR,drive_err
  104.         moveq    #0,d0
  105.         bra.w    .error
  106. .different    move.w    #124*4,d0
  107.         bra.b    .next2
  108. .okfreeh    tst.b    d5
  109.         beq.b    .loaded
  110.         cmp.l    d3,d6            ;block already loaded ?
  111.         beq.b    .loaded
  112.         move.l    d6,d0
  113.         move.l    d0,d3
  114.         bsr    read_fbuffer
  115. .loaded        cmp.l    #1,127*4(a0)        ;ROOT ?
  116.         beq.b    .puthash
  117.         move.l    1*4(a0),d0
  118.         cmp.l    file_parent(a1),d0    ;is it the PARENT
  119.         bne.b    .putlist
  120. .puthash    bsr    calc_hash
  121.         move.l    (a0,d0.w),d6        ;next in hash list
  122.         move.l    file_header(a1),(a0,d0.w)
  123.         bra.b    .savesec
  124. .putlist    move.l    124*4(a0),d6        ;next in hash list
  125.         move.l    file_header(a1),124*4(a0)
  126. .savesec    lea.l    extension,a0
  127.         bsr    calc_sum
  128.         move.l    d3,d0
  129.         bsr    write_fbuffer        ;write back the block
  130.                         ;containing the ref to the file
  131.  
  132. ;-------------- init the file header --
  133.  
  134.         lea.l    secbuf,a4
  135.         moveq    #128-1,d0
  136. .clr        clr.l    (a4)+            ;clear whole block
  137.         dbf    d0,.clr
  138.         lea.l    secbuf,a0
  139.         move.l    #2,(a0)            ;Type 2 (T.SHORT)
  140.         move.l    file_header(a1),1*4(a0)    ;Header Key
  141.         lea.l    108*4(a0),a4
  142.         lea.l    file_name(a1),a0
  143.         moveq    #8-1,d0
  144. .copy_name    move.l    (a0)+,(a4)+        ;copy filename
  145.         dbf    d0,.copy_name
  146.         lea.l    secbuf,a0
  147.         move.l    file_parent(a1),125*4(a0)    ;parent
  148.         move.l    #-3,127*4(a0)        ;sec.type (File-header)
  149.         move.l    d6,124*4(a0)        ;next in hash list
  150.  
  151.         bsr    calc_sum
  152.         move.l    file_header(a1),d0
  153.         bsr    write_fbuffer        ;write new file header block
  154.  
  155.         bsr    update_bitmap
  156.  
  157.         bra.w    .okfile            ;ok, return file_handle
  158.  
  159. ;-------------- open old file --------------
  160.  
  161. .oldfile    bsr    calc_hash
  162. .next        lea.l    extension,a0
  163.         move.l    (a0,d0.w),d0
  164.         bne.b    .oknext
  165.         move.w    #FILENOTFOUND_ERR,drive_err
  166.         moveq    #0,d0
  167.         bra.b    .error
  168. .oknext        bsr    read_fbuffer        ;read next in hash list
  169.         bsr    test_sum
  170.         beq.b    .oksum3
  171.         moveq    #0,d0
  172.         bra.b    .error
  173. .oksum3        lea.l    108*4(a0),a0        ;filename
  174.         bsr    cmp_filename
  175.         beq.b    .found
  176.         move.w    #124*4,d0
  177.         bra.b    .next
  178.  
  179. .found        lea.l    extension,a0
  180.         move.l    d0,file_header(a1)
  181.         move.l    d0,file_extension(a1)
  182.         move.l    81*4(a0),file_size(a1)    ;copy file_size
  183.         cmp.l    #-3,127*4(a0)        ;is it a real file_header ?
  184.         beq.b    .okfile
  185.         tst.l    d7            ;allow to open a dir ?
  186.         beq.b    .nodir
  187.         cmp.l    #2,127*4(a0)        ;is it a directory ?
  188.         beq.b    .okfile
  189. .nodir        move.w    #FILENOTFOUND_ERR,drive_err
  190.         moveq    #0,d0
  191.         bra.b    .error
  192.  
  193. .okfile        move.l    a1,d0            ;return file_handle
  194.  
  195. .error        tst.l    d0
  196.         bne.b    .noerr
  197.         clr.l    (a1)            ;free file_handle
  198. .noerr        movem.l    (a7)+,d1-d7/a0-a4
  199.         tst.l    d0
  200.         rts
  201.  
  202. ;----------------------------------------------------------
  203.  
  204. ;-> d1=ptr on file_handle
  205. ;<- d0=result 0=no error -1=error
  206.  
  207. close_file    movem.l    d1-d7/a0-a4,-(a7)
  208.         tst.l    d1
  209.         beq.b    .endclose
  210.         move.l    d1,a1
  211.         move.l    file_part(a1),a3
  212.         move.l    part_device(a3),a2
  213.         tst.b    file_written(a1)
  214.         beq.b    .notwritten
  215.         bsr    update_bitmap
  216.         lea.l    secbuf,a0
  217.         move.l    file_header(a1),d0
  218.         bsr    read_fbuffer        ;read fileheader
  219.         move.l    file_size(a1),81*4(a0)    ;update filesize
  220.         tst.l    2*4(a0)            ;any block present ?
  221.         beq.b    .noblock
  222.         move.l    77*4(a0),4*4(a0)    ;copy first block no
  223. .noblock    bsr    calc_sum
  224.         bsr    write_fbuffer        ;write correct fileheader
  225.  
  226. .notwritten    bsr    flush_fbuffer
  227.         jsr    MOTOFF_CMD(a2)
  228.         clr.l    (a1)            ;Free file_handle
  229. .endclose    moveq    #0,d0
  230.         movem.l    (a7)+,d1-d7/a0-a4
  231.         rts
  232.  
  233. ;----------------------------------------------------------
  234.  
  235. ;-> d1=ptr on file_handle
  236. ;-> d2=ptr on buffer
  237. ;-> d3=len to read
  238. ;<- d0=result 0=ok -1=error
  239.  
  240. read_file    movem.l    d1-d7/a0-a4,-(a7)
  241.         move.l    d1,a1
  242.         move.l    file_part(a1),a3
  243.         move.l    part_device(a3),a2
  244.  
  245.         move.l    file_size(a1),d4
  246.         sub.l    file_seek(a1),d4    ;max val for len
  247.         cmp.l    d4,d3
  248.         ble.b    .oklen
  249.         move.l    d4,d3            ;truncate len
  250. .oklen        tst.l    d3
  251.         beq.w    .endread
  252.  
  253.         move.l    d2,a4
  254.  
  255. .recheck    move.l    file_extension(a1),d0
  256.         lea.l    extension,a0
  257.         bsr    read_fbuffer        ;read extension block
  258.         bsr    test_sum
  259.         bne.w    .endread
  260.         move.l    file_seek(a1),d0
  261.         sub.l    file_extpos(a1),d0
  262.         cmp.l    #72*512,d0
  263.         blt.b    .inthisext
  264.         move.l    126*4(a0),d0        ;next extension block
  265.         move.l    d0,file_extension(a1)
  266.         add.l    #72*512,file_extpos(a1)
  267.         bra.b    .recheck
  268.  
  269. .inthisext
  270.         move.l    file_seek(a1),d4
  271.         sub.l    file_extpos(a1),d4
  272.         moveq    #9,d1
  273.         lsr.l    d1,d4            ;div 512
  274.         neg.w    d4
  275.         add.w    #71,d4
  276.         lea.l    extension,a0
  277.         lsl.w    #2,d4
  278.         move.l    6*4(a0,d4.w),d0        ;first data block
  279.         lsr.w    #2,d4
  280.         move.l    file_seek(a1),d1
  281.         and.l    #$1ff,d1        ;get offset in first block
  282.         lea.l    secbuf,a0
  283.         bsr    read_fbuffer        ;read first data block
  284.         move.l    #512,d5
  285.         sub.l    d1,d5            ;nb bytes in first block
  286.         cmp.l    d3,d5
  287.         bge.w    .lastread    ;all bytes to read in this block ?
  288.  
  289.         lea.l    secbuf,a0
  290.         add.l    d1,a0
  291.         sub.l    d5,d3
  292.         add.l    d5,file_seek(a1)
  293.         subq.w    #1,d5
  294. .copyf        move.b    (a0)+,(a4)+        ;copy bytes from 1st block
  295.         dbf    d5,.copyf
  296.  
  297. .nextdata    subq.w    #1,d4            ;next block
  298.         bpl.b    .okextension        ;still in this extension ?
  299.         lea.l    extension,a0
  300.         move.l    126*4(a0),d0        ;next extension
  301.         move.l    d0,file_extension(a1)
  302.         bsr    read_fbuffer        ;read next extension block
  303.         bsr    test_sum
  304.         bne.b    .endread
  305.         moveq    #71,d4
  306.         add.l    #72*512,file_extpos(a1)
  307.  
  308. .okextension    lea.l    extension,a0
  309.         lsl.w    #2,d4
  310.         move.l    6*4(a0,d4.w),d0        ;next data block
  311.         lsr.w    #2,d4
  312.         cmp.l    #512,d3            ;nb bytes to read > 1 block ?
  313.         blt.b    .readlast
  314.  
  315.         move.l    a4,a0
  316.         bsr    read_fbuffer        ;read data block
  317.         lea.l    512(a4),a4
  318.         add.l    #512,file_seek(a1)
  319.         sub.l    #512,d3
  320.         bne.b    .nextdata
  321.         bra.b    .endread        ;no more bytes to read
  322.  
  323. .readlast    lea.l    secbuf,a0
  324.         bsr    read_fbuffer
  325.         moveq    #0,d1            ;offset in block=0
  326.  
  327. .lastread    lea.l    secbuf,a0
  328.         add.l    d1,a0
  329.         add.l    d3,file_seek(a1)
  330.         subq.w    #1,d3
  331. .copy        move.b    (a0)+,(a4)+
  332.         dbf    d3,.copy
  333.  
  334. .endread    moveq    #0,d0
  335.         tst.w    drive_err
  336.         beq.b    .noerr
  337.         moveq    #-1,d0
  338. .noerr
  339.         movem.l    (a7)+,d1-d7/a0-a4
  340.         rts
  341.  
  342. ;----------------------------------------------------------
  343.  
  344. ;-> d1=ptr on file_handle
  345. ;-> d2=ptr on buffer
  346. ;-> d3=len to write
  347. ;<- d0=result 0=ok -1=error
  348.  
  349. write_file    movem.l    d1-d7/a0-a4,-(a7)
  350.  
  351.         move.l    d1,a1
  352.         st    file_written(a1)
  353.         move.l    file_part(a1),a3
  354.         move.l    part_device(a3),a2
  355.  
  356.         move.l    file_size(a1),d0
  357.         sub.l    file_seek(a1),d0    ;nb bytes till end of file
  358.         cmp.l    d0,d3
  359.         ble.b    .noappend
  360.  
  361.         tst.l    d0
  362.         beq.b    .noover
  363.         bsr    overwrite        ;overwrite till end of file
  364.         tst.w    drive_err
  365.         bne.b    .end
  366.         add.l    d0,d2            ;new buffer address
  367.         sub.l    d0,d3            ;nb bytes left to write
  368. .noover        move.l    d3,d0
  369.         bsr    append            ;then append
  370.         bra.b    .end
  371.  
  372. .noappend    move.l    d3,d0
  373.         bsr    overwrite
  374.  
  375. .end        bsr    update_bitmap
  376.         moveq    #0,d0
  377.         tst.w    drive_err
  378.         beq.b    .exit
  379.         moveq    #-1,d0
  380.  
  381. .exit        movem.l    (a7)+,d1-d7/a0-a4
  382.         rts
  383.  
  384. ;-> a1=ptr on file_handle
  385. ;-> d0=nb bytes to overwrite
  386. ;-> d2=ptr on buffer
  387. ;-> a2=device
  388. ;-> a3=part
  389.  
  390. overwrite    movem.l    d0-a4,-(a7)
  391.         move.l    d2,a4
  392.         move.l    d0,d3
  393.  
  394. .recheck    move.l    file_extension(a1),d0
  395.         lea.l    extension,a0
  396.         bsr    read_fbuffer        ;read extension block
  397.         bsr    test_sum
  398.         bne.w    .endwrite
  399.         move.l    file_seek(a1),d0
  400.         sub.l    file_extpos(a1),d0
  401.         cmp.l    #72*512,d0
  402.         blt.b    .inthisext
  403.         move.l    126*4(a0),d0        ;next extension block
  404.         move.l    d0,file_extension(a1)
  405.         add.l    #72*512,file_extpos(a1)
  406.         bra.b    .recheck
  407.  
  408. .inthisext    move.l    file_seek(a1),d4
  409.         sub.l    file_extpos(a1),d4
  410.         moveq    #9,d1
  411.         lsr.l    d1,d4            ;div 512
  412.         neg.w    d4
  413.         add.w    #71,d4
  414.         lea.l    extension,a0
  415.         lsl.w    #2,d4
  416.         move.l    6*4(a0,d4.w),d0        ;first data block
  417.         lsr.w    #2,d4
  418.         move.l    file_seek(a1),d1
  419.         and.l    #$1ff,d1        ;get offset in first block
  420.         lea.l    secbuf,a0
  421.         bsr    read_fbuffer        ;read first data block
  422.         move.l    #512,d5
  423.         sub.l    d1,d5            ;nb bytes in first block
  424.         cmp.l    d3,d5
  425.         bge.w    .lastwrite        ;all bytes to write in this block ?
  426.  
  427.         lea.l    secbuf,a0
  428.         add.l    d1,a0
  429.         sub.l    d5,d3
  430.         add.l    d5,file_seek(a1)
  431.         subq.w    #1,d5
  432. .copyf        move.b    (a4)+,(a0)+        ;copy bytes to 1st block
  433.         dbf    d5,.copyf
  434.  
  435.         lea.l    secbuf,a0
  436.         bsr    write_fbuffer        ;write back first block
  437.  
  438. .nextdata    subq.w    #1,d4            ;next block
  439.         bpl.b    .okextension        ;still in this extension ?
  440.         lea.l    extension,a0
  441.         move.l    126*4(a0),d0        ;next extension
  442.         move.l    d0,file_extension(a1)
  443.         bsr    read_fbuffer        ;read next extension block
  444.         bsr    test_sum
  445.         bne.b    .endwrite
  446.         moveq    #71,d4
  447.         add.l    #72*512,file_extpos(a1)
  448.  
  449. .okextension    lea.l    extension,a0
  450.         lsl.w    #2,d4
  451.         move.l    6*4(a0,d4.w),d0        ;next data block
  452.         lsr.w    #2,d4
  453.         cmp.l    #512,d3            ;nb bytes to write > 1 block ?
  454.         blt.b    .writelast
  455.  
  456.         move.l    a4,a0
  457.         bsr    write_fbuffer        ;write data block
  458.         lea.l    512(a4),a4
  459.         sub.l    #512,d3
  460.         add.l    #512,file_seek(a1)
  461.         bne.b    .nextdata
  462.         bra.b    .endwrite        ;no more bytes to write
  463.  
  464. .writelast    lea.l    secbuf,a0
  465.         bsr    read_fbuffer
  466.         moveq    #0,d1            ;offset in block=0
  467.  
  468. .lastwrite    lea.l    secbuf,a0
  469.         add.l    d1,a0
  470.         add.l    d3,file_seek(a1)
  471.         subq.w    #1,d3
  472. .copy        move.b    (a4)+,(a0)+
  473.         dbf    d3,.copy
  474.  
  475.         lea.l    secbuf,a0
  476.         bsr    write_fbuffer        ;write back last block
  477.  
  478. .endwrite
  479.         movem.l    (a7)+,d0-a4
  480.         rts
  481.  
  482. ;-> a1=ptr on file_handle
  483. ;-> d0=nb bytes to append
  484. ;-> d2=ptr on buffer
  485. ;-> a2=device
  486. ;-> a3=part
  487.  
  488. append        movem.l    d0-a4,-(a7)
  489.         move.l    d2,a4
  490.         move.l    d0,d3
  491.  
  492. .recheck    move.l    file_extension(a1),d0
  493.         lea.l    extension,a0
  494.         bsr    read_fbuffer        ;read extension block
  495.         bsr    test_sum
  496.         bne.w    .error
  497.         move.l    file_seek(a1),d0
  498.         sub.l    file_extpos(a1),d0
  499.         cmp.l    #72*512,d0
  500.         blt.w    .inthisext
  501.         move.l    126*4(a0),d0        ;next extension block
  502.         bne.b    .okhere            ;exists ?
  503.  
  504.         bsr    alloc_block        ;alloc new extension block
  505.         bpl.b    .okalloc
  506.         bsr    delete_fh
  507.         move.w    #DISKFULL_ERR,drive_err
  508.         bra.w    .error
  509. .okalloc    lea.l    extension,a0
  510.         move.l    d0,126*4(a0)        ;put in extension block list
  511.         move.l    d0,-(a7)
  512.         bsr    calc_sum
  513.         move.l    file_extension(a1),d0
  514.         bsr    write_fbuffer        ;write back extension block
  515.         move.l    (a7)+,d0        ;restore new extension block no
  516.         lea.l    extension,a0
  517.         moveq    #128-1,d1
  518. .clrex        clr.l    (a0)+            ;clear new extension block
  519.         dbf    d1,.clrex
  520.         lea.l    extension,a0
  521.         move.l    #$10,(a0)            ;T.LIST
  522.         move.l    d0,1*4(a0)            ;header key
  523.         move.l    file_header(a1),125*4(a0)    ;parent
  524.         move.l    #-3,127*4(a0)            ;sec.type
  525.         bsr    calc_sum
  526.         bsr    write_fbuffer        ;write back new extension block
  527.  
  528. .okhere        move.l    d0,file_extension(a1)
  529.         add.l    #72*512,file_extpos(a1)
  530.         bra.w    .recheck
  531.  
  532. .inthisext    move.l    file_seek(a1),d4
  533.         sub.l    file_extpos(a1),d4
  534.         move.l    d4,d0
  535.         moveq    #9,d1
  536.         lsr.l    d1,d4            ;div 512
  537.         neg.w    d4
  538.         add.w    #71,d4
  539.         lea.l    extension,a0
  540.         and.w    #$1ff,d0        ;need to alloc a new block ?
  541.         beq.w    .aligned
  542.         lsl.w    #2,d4
  543.         move.l    6*4(a0,d4.w),d0
  544.         lsr.w    #2,d4
  545.         lea.l    secbuf,a0
  546.         bsr    read_fbuffer
  547.         move.l    file_seek(a1),d1
  548.         and.l    #$1ff,d1
  549.         add.l    d1,a0
  550.         neg.l    d1
  551.         add.l    #512,d1            ;nb bytes left in this block
  552.         cmp.l    d3,d1
  553.         ble.b    .noall
  554.         move.l    d3,d1
  555. .noall        add.l    d1,file_size(a1)
  556.         add.l    d1,file_seek(a1)
  557.         sub.l    d1,d3
  558.         bra.b    .godbf
  559. .copyb        move.b    (a4)+,(a0)+        ;copy data in last block
  560. .godbf        dbf    d1,.copyb
  561.         lea.l    secbuf,a0
  562.         bsr    write_fbuffer        ;write back last block
  563.         tst.l    d3
  564.         beq.w    .endwrite
  565.  
  566. .nextwrite    subq.w    #1,d4
  567.         bpl.w    .aligned
  568.         bsr    alloc_block        ;get new extension block
  569.         bpl.b    .okalloc3
  570.         lea.l    extension,a0
  571.         move.l    file_extension(a1),d0
  572.         bsr    calc_sum
  573.         bsr    write_fbuffer        ;write back last extension
  574.         bsr    delete_fh
  575.         move.w    #DISKFULL_ERR,drive_err
  576.         bra.w    .error
  577. .okalloc3    lea.l    extension,a0
  578.         move.l    d0,126*4(a0)        ;put in extension list
  579.         move.l    d0,-(a7)
  580.         bsr    calc_sum
  581.         move.l    file_extension(a1),d0
  582.         bsr    write_fbuffer        ;write back old extension
  583.         move.l    (a7)+,d0
  584.         lea.l    extension,a0
  585.         moveq    #128-1,d1
  586. .clrex2        clr.l    (a0)+            ;clear new extension block
  587.         dbf    d1,.clrex2
  588.         lea.l    extension,a0
  589.         move.l    #$10,(a0)            ;T.LIST
  590.         move.l    d0,1*4(a0)            ;header key
  591.         move.l    file_header(a1),125*4(a0)    ;parent
  592.         move.l    #-3,127*4(a0)            ;sec.type
  593.         move.l    d0,file_extension(a1)
  594.         add.l    #72*512,file_extpos(a1)
  595.         bsr    calc_sum
  596.         bsr    write_fbuffer        ;write back new extension block
  597.         moveq    #71,d4
  598.  
  599. .aligned    bsr    alloc_block        ;get new data block
  600.         bpl.b    .okalloc2
  601.         lea.l    extension,a0
  602.         move.l    file_extension(a1),d0
  603.         bsr    calc_sum
  604.         bsr    write_fbuffer        ;write back last extension
  605.         bsr    delete_fh
  606.         move.w    #DISKFULL_ERR,drive_err
  607.         bra.w    .error
  608. .okalloc2    lea.l    extension,a0
  609.         addq.l    #1,2*4(a0)        ;1 block de plus dans la list
  610.         lsl.w    #2,d4
  611.         move.l    d0,6*4(a0,d4.w)
  612.         lsr.w    #2,d4
  613.         move.l    a4,a0
  614.         cmp.l    #512,d3
  615.         ble.b    .slow
  616.         bsr    write_fbuffer        ;write new data block
  617.         bra.b    .okfast
  618. .slow        bsr    write_fbuffer        ;write new data block
  619. .okfast
  620.         move.l    #512,d0
  621.         cmp.l    d0,d3
  622.         ble.b    .last
  623.         add.l    d0,a4
  624.         sub.l    d0,d3            ;reduce nb bytes left to write
  625.         add.l    d0,file_seek(a1)
  626.         add.l    d0,file_size(a1)
  627.         bra.w    .nextwrite
  628.  
  629. .last        add.l    d3,file_size(a1)
  630.         add.l    d3,file_seek(a1)
  631.  
  632.         lea.l    extension,a0
  633.         move.l    file_extension(a1),d0
  634.         bsr    calc_sum
  635.         bsr    write_fbuffer        ;write back last extension
  636.  
  637. .endwrite
  638. .error
  639.         movem.l    (a7)+,d0-a4
  640.         rts
  641.  
  642. ;----------------------------------------------------------
  643.  
  644. ;-> d1=ptr on file_handle
  645. ;-> d2=seek offset
  646. ;-> d3=mode -1=beginning, 0=current, 1=end
  647.  
  648. seek_file    movem.l    d1-d7/a0-a4,-(a7)
  649.         move.l    d1,a1
  650.         tst.l    d3
  651.         bpl.b    .nobegin
  652.  
  653. ;-------------- beginning --------
  654.  
  655.         cmp.l    file_seek(a1),d2
  656.         bge.b    .noback
  657.         move.l    file_header(a1),file_extension(a1)
  658.         clr.l    file_extpos(a1)
  659.         move.l    d2,file_seek(a1)
  660.         bra.b    .end
  661. .noback        move.l    d2,file_seek(a1)
  662.         bra.b    .end
  663.  
  664. ;-------------- current ----------
  665.  
  666. .nobegin    tst.l    d3
  667.         bne.b    .nocurrent
  668.         tst.l    d2
  669.         bpl.b    .okpos
  670.         move.l    file_header(a1),file_extension(a1)
  671.         clr.l    file_extpos(a1)
  672. .okpos        add.l    d2,file_seek(a1)
  673.         bra.b    .end
  674.  
  675. ;-------------- end --------------
  676.  
  677. .nocurrent    move.l    file_size(a1),d1
  678.         sub.l    d2,d1
  679.         cmp.l    file_seek(a1),d1
  680.         bge.b    .noback2
  681.         move.l    file_header(a1),file_extension(a1)
  682.         clr.l    file_extpos(a1)
  683. .noback2    move.l    d1,file_seek(a1)
  684.  
  685. .end        move.l    file_seek(a1),d0
  686.         cmp.l    file_size(a1),d0    ;bigger than max val ?
  687.         ble.b    .okmax
  688.         move.l    file_size(a1),file_seek(a1)
  689. .okmax        tst.l    file_seek(a1)        ;negative ?
  690.         bpl.b    .okmin
  691.         clr.l    file_seek(a1)
  692. .okmin
  693.         movem.l    (a7)+,d1-d7/a0-a4
  694.         rts
  695.  
  696. ;-----------------------------------------------------
  697.  
  698. ;-> d1=ptr on dirname (ended by a zero)
  699.  
  700. create_dir    movem.l    d0-d7/a0-a4,-(a7)
  701.         st    disk_op
  702.         move.l    d1,d6            ;copy of full filename* in d6
  703.         lea.l    file_handle1,a1
  704.         tst.l    (a1)
  705.         beq.b    .okfree
  706.         lea.l    file_handle2,a1
  707.         tst.l    (a1)
  708.         beq.b    .okfree
  709.         moveq    #0,d0
  710.         bra.w    .error
  711.  
  712. .okfree        bsr    find_partition
  713.         tst.l    d0
  714.         beq.w    .error
  715.         move.l    d0,a3
  716.         move.l    d0,file_part(a1)
  717.         move.l    d2,file_parent(a1)
  718.         clr.l    file_seek(a1)
  719.         clr.l    file_extpos(a1)
  720.         sf    file_written(a1)
  721.  
  722.         bsr    copy_name        ;set BCPL name into filehandle
  723.  
  724.         move.l    part_device(a3),a2
  725.         lea.l    extension,a0
  726.         move.l    file_parent(a1),d0
  727.         move.l    d0,d3
  728.         bsr    read_fbuffer        ;read ROOT or DIR
  729.         bsr    test_sum
  730.         bne.w    .error
  731.  
  732.         clr.l    file_size(a1)
  733.  
  734.         bsr    alloc_block        ;find block for dir_header
  735.         bpl.b    .okhead
  736.         move.w    #DISKFULL_ERR,drive_err
  737.         moveq    #0,d0
  738.         bra.w    .error
  739. .okhead        move.l    d0,file_header(a1)
  740.         move.l    d0,file_extension(a1)
  741.         bsr    calc_hash
  742.         move.l    d3,d6            ;d6=place where to ins. in hash
  743.         sf    d5            ;signal for d6 found
  744. .next2        lea.l    extension,a0
  745.         move.l    (a0,d0.w),d0        ;find end of hash list
  746.         beq.b    .okfreeh
  747.         tst.b    d5            ;already found place where
  748.         bne.b    .foundins        ;to insert in hash list ?
  749.         cmp.l    file_header(a1),d0
  750.         bls.b    .foundins
  751.         st    d5
  752.         move.l    d3,d6            ;d6=place where to ins. in hash
  753. .foundins    move.l    d0,d3            ;d3=no of actual loaded block
  754.         bsr    read_fbuffer        ;read next in hash list
  755.         bsr    test_sum
  756.         beq.b    .oksum2
  757.         move.l    file_header(a1),d0
  758.         bsr    free_block
  759.         bsr    update_bitmap
  760.         moveq    #0,d0
  761.         bra.w    .error
  762. .oksum2        lea.l    108*4(a0),a0
  763.         bsr    cmp_filename        ;file already exists ?
  764.         bne.b    .different
  765.         move.l    file_header(a1),d0
  766.         bsr    free_block
  767.         bsr    update_bitmap
  768.         move.w    #FILEEXIST_ERR,drive_err
  769.         moveq    #0,d0
  770.         bra.w    .error
  771. .different    move.w    #124*4,d0
  772.         bra.b    .next2
  773. .okfreeh    tst.b    d5
  774.         beq.b    .loaded
  775.         cmp.l    d3,d6            ;block already loaded ?
  776.         beq.b    .loaded
  777.         move.l    d6,d0
  778.         move.l    d0,d3
  779.         bsr    read_fbuffer
  780. .loaded        cmp.l    #1,127*4(a0)        ;ROOT ?
  781.         beq.b    .puthash
  782.         move.l    1*4(a0),d0
  783.         cmp.l    file_parent(a1),d0    ;is it the PARENT
  784.         bne.b    .putlist
  785. .puthash    bsr    calc_hash
  786.         move.l    (a0,d0.w),d6        ;next in hash list
  787.         move.l    file_header(a1),(a0,d0.w)
  788.         bra.b    .savesec
  789. .putlist    move.l    124*4(a0),d6        ;next in hash list
  790.         move.l    file_header(a1),124*4(a0)
  791. .savesec    lea.l    extension,a0
  792.         bsr    calc_sum
  793.         move.l    d3,d0
  794.         bsr    write_fbuffer        ;write back the block
  795.                         ;containing the ref to the dir
  796.  
  797. ;-------------- init the dir block --
  798.  
  799.         lea.l    secbuf,a4
  800.         moveq    #128-1,d0
  801. .clr        clr.l    (a4)+            ;clear whole block
  802.         dbf    d0,.clr
  803.         lea.l    secbuf,a0
  804.         move.l    #2,(a0)            ;Type 2 (T.SHORT)
  805.         move.l    file_header(a1),1*4(a0)    ;Header Key
  806.         lea.l    108*4(a0),a4
  807.         lea.l    file_name(a1),a0
  808.         moveq    #8-1,d0
  809. .copy_name    move.l    (a0)+,(a4)+        ;copy dirname
  810.         dbf    d0,.copy_name
  811.         lea.l    secbuf,a0
  812.         move.l    file_parent(a1),125*4(a0)    ;parent
  813.         move.l    #2,127*4(a0)        ;sec.type (dir)
  814.         move.l    d6,124*4(a0)        ;next in hash list
  815.  
  816.         bsr    calc_sum
  817.         move.l    file_header(a1),d0
  818.         bsr    write_fbuffer        ;write new dir block
  819.  
  820.         bsr    update_bitmap
  821.  
  822.         bsr    flush_fbuffer
  823.         jsr    UPDATE_CMD(a2)
  824.         jsr    MOTOFF_CMD(a2)
  825.  
  826. .error        clr.l    (a1)            ;free file_handle
  827.         movem.l    (a7)+,d0-d7/a0-a4
  828.         rts
  829.  
  830. ;----------------------------------------------------------
  831. ;-------------- change current directory (CD) -------------
  832.  
  833. ;-> d1=ptr on new current path name
  834.  
  835. change_dir    movem.l    d0-d7/a0-a4,-(a7)
  836.         st    disk_op
  837.  
  838.         move.l    d1,a0
  839.  
  840. .seekend    tst.b    (a0)+
  841.         bne.b    .seekend
  842.         subq.l    #2,a0            ;go on last char
  843.         cmp.l    d1,a0
  844.         blt.b    .empty
  845.         cmp.b    #'/',(a0)+
  846.         beq.b    .already
  847.         cmp.b    #':',-1(a0)        ;device ?
  848.         beq.b    .already
  849.         move.b    #'/',(a0)+
  850. .already    move.b    #'a',(a0)+    ;dummy filename for find partition
  851.         sf    (a0)+
  852. .empty
  853.         move.l    d1,d6            ;copy of full filename* in d6
  854.         lea.l    file_handle1,a1
  855.         tst.l    (a1)
  856.         beq.b    .okfree
  857.         lea.l    file_handle2,a1
  858.         tst.l    (a1)
  859.         beq.b    .okfree
  860.         moveq    #0,d0
  861.         bra.w    .error
  862.  
  863. .okfree        bsr    find_partition
  864.         tst.l    d0
  865.         beq.b    .error
  866.         movem.l    d0/d2,current_dir
  867.  
  868.         bsr    flush_fbuffer
  869.         move.l    d0,a3
  870.         move.l    part_device(a3),a2
  871.         jsr    MOTOFF_CMD(a2)
  872.  
  873. .error        movem.l    (a7)+,d0-d7/a0-a4
  874.         rts
  875.  
  876. ;----------------------------------------------------------
  877. ;-------------- Print path --------------------------------
  878.  
  879. ;-> d0=block no of actual dir
  880. ;-> a3=partition
  881.  
  882. print_path    movem.l    d0/a0-a4,-(a7)
  883.         st    disk_op
  884.         move.l    part_device(a3),a2
  885.         lea.l    general_txt+80,a4
  886. .loop        lea.l    secbuf,a0
  887.         bsr    read_fbuffer
  888.         cmp.l    #1,127*4(a0)        ;ROOT ?
  889.         beq.b    .root
  890.         move.b    #'/',-(a4)
  891.         bsr.b    .check_len
  892.         bne.b    .out
  893.         bsr    .put_name
  894.         bsr.b    .check_len
  895.         bne.b    .out
  896.         move.l    125*4(a0),d0        ;get parent
  897.         bne.b    .loop
  898.         bra.b    .err
  899.  
  900. .root        move.b    #':',-(a4)
  901.         bsr.b    .check_len
  902.         bne.b    .out
  903.         lea.l    part_name(a3),a0
  904.         bsr    .put_name2
  905.  
  906. .out        move.l    a4,a0
  907.         bsr    print
  908.  
  909. .err        movem.l    (a7)+,d0/a0-a4
  910.         rts
  911.  
  912.  
  913. ;put BCPL name from secbuf to -(a4)
  914.  
  915. .put_name    move.l    a0,-(a7)
  916.         lea.l    secbuf+108*4,a0
  917.         bsr    .put_name2
  918.         move.l    (a7)+,a0
  919.         rts
  920.  
  921. ;put BCPL name from a0 to -(a4)
  922.  
  923. .put_name2    movem.l    d0/a0,-(a7)
  924.         moveq    #0,d0
  925.         move.b    (a0)+,d0        ;name length
  926.         add.l    d0,a0
  927.         bra.b    .godbf
  928. .copy        move.b    -(a0),-(a4)
  929.         bsr.b    .check_len
  930.         bne.b    .outn
  931. .godbf        dbf    d0,.copy
  932. .outn        movem.l    (a7)+,d0/a0
  933.         rts
  934.  
  935. ;-> a4
  936. ;<- FLAGS 0=len ok -1=full
  937. .check_len    movem.l    d0/a4,-(a7)
  938.         cmp.l    #general_txt+2,a4
  939.         bne.b    .nofull
  940.         move.l    #'....',(a4)
  941.         moveq    #-1,d0
  942.         bra.b    .outl
  943. .nofull        moveq    #0,d0
  944. .outl        movem.l    (a7)+,d0/a4
  945.         rts
  946.  
  947. ;----------------------------------------------------------
  948. ;-------------- Get Free Blocks  --------------------------
  949.  
  950. ;-> a3=ptr on partition
  951.  
  952. get_free_blocks
  953.         st    disk_op
  954.         move.l    part_nbsec(a3),d0
  955.         lsr.l    #1,d0            ;ROOT block no
  956.         lea.l    secbuf,a0
  957.         bsr    read_fbuffer        ;read ROOT block
  958.         bsr    test_sum
  959.         beq.b    .oksum
  960.         moveq    #0,d0
  961.         bra.w    .error
  962. .oksum
  963. .error
  964.         rts
  965.  
  966. ;----------------------------------------------------------
  967. ;-------------- ExNext ------------------------------------
  968.  
  969. ;-> d1=ptr on dir path to list or previous examined file_handle
  970. ;<- d0=file_handle on next file 0=no next -1=error
  971. ;<- d1=ptr on partition of dir (returned only on first call)
  972. ;<- d2=block no of parent (returned only on first call)
  973.  
  974. ExNext
  975.         st    disk_op
  976.         movem.l    d1-a4,-(a7)
  977.         cmp.l    #file_handle1,d1
  978.         beq.b    .next
  979.         cmp.l    #file_handle2,d1
  980.         bne.b    .first
  981. .next
  982.         move.l    d1,a1
  983.         move.l    file_part(a1),a3
  984.         move.l    part_device(a3),a2
  985.         lea.l    secbuf,a0
  986.         move.l    file_header(a1),d0
  987.         bsr    read_fbuffer        ;read previous file header
  988.         bsr    test_sum
  989.         bne.w    .error2
  990.         move.l    124*4(a0),d0        ;next in hash list
  991.         bne.w    .found
  992.         bsr    calc_hash
  993.         lea.l    extension,a0        ;dir block here
  994.         lea.l    4(a0,d0.w),a0        ;next in hash table
  995. .seek2        cmp.l    #extension+78*4,a0    ;end of hash table ?
  996.         beq.w    .enddir
  997.         move.l    (a0)+,d0
  998.         beq.b    .seek2
  999.         bra.w    .found
  1000.  
  1001. ;-------------------------------------------
  1002.  
  1003. .first        move.l    d1,a0            ;path name
  1004. .seekend    tst.b    (a0)+
  1005.         bne.b    .seekend
  1006.         subq.l    #2,a0            ;go on last char
  1007.         cmp.l    d1,a0
  1008.         bge.b    .noempty
  1009.         move.l    d1,a0
  1010.         bra.b    .already
  1011. .noempty    cmp.b    #'/',(a0)+
  1012.         beq.b    .already
  1013.         cmp.b    #':',-1(a0)        ;device ?
  1014.         beq.b    .already
  1015.         move.b    #'/',(a0)+
  1016. .already    move.b    #'a',(a0)+    ;dummy filename for find partition
  1017.         sf    (a0)+
  1018.  
  1019.         lea.l    file_handle1,a1
  1020.         tst.l    (a1)
  1021.         beq.b    .okfree
  1022.         lea.l    file_handle2,a1
  1023.         tst.l    (a1)
  1024.         beq.b    .okfree
  1025.         moveq    #0,d0
  1026.         bra.w    .error
  1027.  
  1028. .okfree        bsr    find_partition
  1029.         tst.l    d0
  1030.         beq.w    .error
  1031.         move.l    d0,(a1)
  1032.         move.l    d0,(a7)            ;return partition in d1
  1033.         move.l    d2,4(a7)        ;return parent block no in d2
  1034.         move.l    d0,a3
  1035.         move.l    part_device(a3),a2
  1036.         move.l    d2,file_parent(a1)
  1037.         move.l    file_parent(a1),d0
  1038.         lea.l    extension,a0
  1039.         bsr    read_fbuffer        ;read dir block
  1040.         bsr    test_sum
  1041.         bne.b    .error2
  1042.         lea.l    6*4(a0),a4        ;start of hashtable
  1043.         moveq    #72-1,d1        ;hashtable size
  1044. .seekfirst    move.l    (a4)+,d0        ;find first file
  1045.         bne.b    .found
  1046.         dbf    d1,.seekfirst
  1047. .enddir        clr.l    (a1)
  1048.         moveq    #0,d0            ;end of dir
  1049.         bra.b    .endx
  1050.  
  1051. .found        move.l    d0,file_header(a1)
  1052.         lea.l    secbuf,a0
  1053.         bsr    read_fbuffer        ;read first file header
  1054.         bsr    test_sum
  1055.         bne.b    .error2
  1056.         move.l    81*4(a0),file_size(a1)
  1057.         lea.l    file_name(a1),a4
  1058.         cmp.l    #-3,127*4(a0)    ;is it a file_header ? or a dir ?
  1059.         sne    file_dir(a1)
  1060.         lea.l    108*4(a0),a0
  1061.         moveq    #8-1,d0
  1062. .copyn        move.l    (a0)+,(a4)+        ;copy BCPL filename
  1063.         dbf    d0,.copyn
  1064.  
  1065.         move.l    a1,d0
  1066.         bra.b    .endx
  1067.  
  1068. .error2        clr.l    (a1)            ;free file_handle
  1069. .error        moveq    #-1,d0
  1070.         bra.b    .out
  1071.  
  1072. .endx        tst.w    drive_err
  1073.         bne.b    .error2
  1074.  
  1075. .out        movem.l    (a7)+,d1-a4
  1076.         rts
  1077.  
  1078. ;----------------------------------------------------------
  1079.  
  1080. ;<- d1=ptr on filename to delete (or empty directory)
  1081.  
  1082. delete_file    movem.l    d0-d2/a1,-(a7)
  1083.         moveq    #1,d2            ;mode old file or old dir
  1084.         bsr    open_file
  1085.         tst.l    d0
  1086.         beq.b    .err
  1087.         move.l    d0,a1
  1088.         bsr    delete_fh
  1089.         clr.l    (a1)            ;free file_handle
  1090. .err        movem.l    (a7)+,d0-d2/a1
  1091.         rts
  1092.  
  1093.  
  1094. ;<- a1=file_handle
  1095.  
  1096. delete_fh    movem.l    d0-a4,-(a7)
  1097.         st    disk_op
  1098.         move.l    file_part(a1),a3
  1099.         move.l    part_device(a3),a2
  1100.         move.l    file_parent(a1),d0
  1101.         move.l    d0,d3
  1102.         lea.l    extension,a0
  1103.         bsr    read_fbuffer        ;read PARENT dir
  1104.         bsr    test_sum
  1105.         bne.w    .error
  1106.  
  1107.         move.l    file_header(a1),d1
  1108.  
  1109.         bsr    calc_hash
  1110. .next        cmp.l    (a0,d0.w),d1
  1111.         beq.b    .found
  1112.         move.l    (a0,d0.w),d0
  1113.         beq.w    .error            ;should never happen
  1114.         move.l    d0,d3
  1115.         bsr    read_fbuffer
  1116.         bsr    test_sum
  1117.         bne.w    .error
  1118.         move.w    #124*4,d0
  1119.         bra.b    .next
  1120. .found        move.w    d0,d2
  1121.         move.l    d1,d0
  1122.         lea.l    secbuf,a0
  1123.         bsr    read_fbuffer        ;read file header
  1124.         bsr    test_sum
  1125.         bne.w    .error
  1126.  
  1127.         cmp.l    #1,127*4(a0)
  1128.         bne.b    .noroot
  1129. .notempty    move.w    #NOTEMPTY_ERR,drive_err
  1130.         bra.w    .error
  1131. .noroot        cmp.l    #2,127*4(a0)
  1132.         bne.b    .nodir
  1133.         lea.l    6*4(a0),a0
  1134.         moveq    #72-1,d0
  1135. .check        tst.l    (a0)+            ;dir is empty ?
  1136.         bne.b    .notempty
  1137.         dbf    d0,.check
  1138.         lea.l    secbuf,a0
  1139. .nodir
  1140.         move.l    124*4(a0),d0        ;next in hash chain
  1141.         lea.l    extension,a0
  1142.         move.l    d0,(a0,d2.w)
  1143.         move.l    d3,d0
  1144.         bsr    calc_sum
  1145.         bsr    write_fbuffer    ;write back block before file_header
  1146.  
  1147.         lea.l    extension,a0
  1148.         move.l    file_header(a1),d0
  1149.         bsr    read_fbuffer        ;file_header in extension
  1150.         bsr    test_sum
  1151.         bne.b    .error
  1152.  
  1153.         move.l    file_header(a1),d0
  1154.         bsr    free_block        ;free file_header
  1155.  
  1156. .next_ext    lea.l    extension,a0
  1157.         move.l    2*4(a0),d1        ;nb blocks
  1158.         lea.l    78*4(a0),a4
  1159.         bra.b    .godbf
  1160. .loop        move.l    -(a4),d0
  1161.         bsr    free_block
  1162. .godbf        dbf    d1,.loop
  1163.         move.l    126*4(a0),d0        ;next extension ?
  1164.         beq.b    .end
  1165.         bsr    read_fbuffer        ;read next extension
  1166.         bsr    test_sum
  1167.         bne.b    .error
  1168.         bsr    free_block        ;free extension block
  1169.         bra.b    .next_ext
  1170.  
  1171. .end
  1172. .error        bsr    update_bitmap
  1173.  
  1174.         bsr    flush_fbuffer
  1175.  
  1176.         movem.l    (a7)+,d0-a4
  1177.         rts
  1178.  
  1179.  
  1180. ;----------------------------------------------------------
  1181.  
  1182. ;-> d1=filename
  1183. ;<- d0=ptr on partition structure (0=error)
  1184. ;<- d1=ptr on filename (without path)
  1185. ;<- d2=dir key where the file is
  1186.  
  1187. find_partition    movem.l    d3-d7/a0-a4,-(a7)
  1188.         st    disk_op
  1189.         move.l    d1,d7
  1190.  
  1191.         move.l    current_dir,a3        ;default partition
  1192.         move.l    current_dir+4,d6    ;default dir
  1193.  
  1194.         lea.l    part_name(a3),a0
  1195.         lea.l    part_nametemp,a1
  1196.         moveq    #8-1,d0            ;copy partition name
  1197. .copyn        move.l    (a0)+,(a1)+        ;in case there isn't a device:
  1198.         dbf    d0,.copyn        ;in the path
  1199.  
  1200.         move.l    d7,a0
  1201. .seek        tst.b    (a0)
  1202.         beq.w    .endofname
  1203.         cmp.b    #':',(a0)+        ;seek device name (ex. HD0: )
  1204.         bne.b    .seek
  1205.         subq.l    #1,a0
  1206.         sub.l    d7,a0
  1207.         move.l    a0,d0
  1208.         cmp.l    #30,d0
  1209.         ble.b    .oksize
  1210.         moveq    #30,d0
  1211. .oksize        lea.l    part_nametemp,a1
  1212.  
  1213.         move.l    a1,a0
  1214.         moveq    #8-1,d1
  1215. .clr        clr.l    (a0)+            ;clear part_nametemp
  1216.         dbf    d1,.clr
  1217.  
  1218.         move.b    d0,(a1)+        ;write len of name
  1219.         move.l    d7,a0
  1220.         move.w    d0,d1
  1221.         bra.b    .godbf
  1222. .copyname    move.b    (a0)+,d0
  1223.         bsr    upper_case
  1224.         move.b    d0,(a1)+        ;copy part_name
  1225. .godbf        dbf    d1,.copyname
  1226.         addq.l    #1,a0            ;skip ':' char
  1227.         move.l    a0,d7
  1228.  
  1229.         lea.l    part_nametemp,a0
  1230.  
  1231.         lea.l    floppy0,a3        ;find partition structure
  1232.  
  1233. .seek2        lea.l    part_name(a3),a1
  1234.         move.l    a0,a4
  1235.         moveq    #8-1,d0
  1236. .cmpname    cmpm.l    (a1)+,(a4)+
  1237.         bne.b    .notsame
  1238.         dbf    d0,.cmpname
  1239.         move.l    part_nbsec(a3),d6
  1240.         lsr.l    #1,d6            ;ROOT block is default dir
  1241.         bra.b    .endofname
  1242. .notsame    move.l    part_next(a3),d0
  1243.         beq.b    .err
  1244.         move.l    d0,a3
  1245.         bra.b    .seek2
  1246. .err        move.w    #DEVICENOTFOUND_ERR,drive_err
  1247.         moveq    #0,d0
  1248.         bra.w    .end
  1249.  
  1250. ;-------------- find directory -------------
  1251.  
  1252. .endofname    bsr    test_change
  1253.         tst.w    drive_err        ;test if an error occured
  1254.         bne.b    .exit
  1255.         cmp.l    #$444f5301,part_filesystem(a3)    ;DOS\1 FFS ?
  1256.         beq.b    .okFFS
  1257.         cmp.l    #$444f5303,part_filesystem(a3)    ;DOS\3 FFS INTL ?
  1258.         beq.b    .okFFS
  1259.         move.w    #NOFFS_ERR,drive_err
  1260. .exit        moveq    #0,d0
  1261.         bra.w    .end
  1262. .okFFS        move.l    part_device(a3),a2
  1263.         move.l    d7,a0
  1264. .seekslash    tst.b    (a0)
  1265.         beq.w    .nomore
  1266.         cmp.b    #"/",(a0)+
  1267.         bne.b    .seekslash
  1268.         subq.l    #1,a0
  1269.         cmp.l    d7,a0
  1270.         bne.b    .noparent
  1271.         addq.l    #1,d7                ;skip '/' char
  1272.         move.l    d6,d0
  1273.         lea.l    secbuf,a0
  1274.         bsr    read_fbuffer            ;read actual dir
  1275.         bsr    test_sum
  1276.         bne.w    .error
  1277.         move.l    125*4(a0),d6            ;parent
  1278.         bne.b    .okFFS                ;found a parent ?
  1279.         move.w    #ILLEGALPATH_ERR,drive_err
  1280.         moveq    #0,d0
  1281.         bra.w    .end
  1282.  
  1283. .noparent    sub.l    d7,a0
  1284.         move.l    a0,d2                ;dir_name len
  1285.         lea.l    part_nametemp,a1
  1286.         move.l    a1,a0
  1287.         moveq    #8-1,d1
  1288. .clr2        clr.l    (a1)+
  1289.         dbf    d1,.clr2
  1290.         move.b    d2,(a0)+            ;set dir_name len
  1291.         move.l    d7,a1
  1292.         bra.b    .godbf2
  1293. .copydn        move.b    (a1)+,(a0)+            ;copy dir_name
  1294. .godbf2        dbf    d2,.copydn
  1295.         move.l    a1,d7
  1296.         addq.l    #1,d7                ;skip '/' char
  1297.  
  1298.         lea.l    secbuf,a0
  1299.         move.l    d6,d0
  1300.         bsr    read_fbuffer            ;read actual dir
  1301.         bsr    test_sum
  1302.         bne.b    .error
  1303.  
  1304.         lea.l    part_nametemp,a0
  1305.         move.b    part_filesystem+3(a3),d0    ;get DOSTYPE
  1306.         bsr    calc_hash2
  1307. .nextdir    lea.l    secbuf,a0
  1308.         move.l    (a0,d0.w),d6            ;read hash ptr
  1309.         beq.b    .illegal
  1310.         move.l    d6,d0
  1311.         bsr    read_fbuffer            ;read new dir
  1312.         bsr    test_sum
  1313.         bne.b    .error
  1314.         lea.l    part_nametemp,a0
  1315.         lea.l    secbuf+108*4,a1
  1316.         bsr    cmp_filename2
  1317.         beq.b    .okdirname
  1318.         move.w    #124*4,d0
  1319.         bra.b    .nextdir
  1320. .okdirname    cmp.l    #2,secbuf+127*4            ;is it a dir ?
  1321.         beq.w    .okFFS
  1322. .illegal    move.w    #ILLEGALPATH_ERR,drive_err
  1323. .error        moveq    #0,d0                ;not a dir, then error
  1324.         bra.b    .end
  1325.  
  1326. .nomore        move.l    d7,a0
  1327.         tst.b    (a0)                ;empty filename ?
  1328.         bne.b    .okfilename
  1329.         move.w    #FILEEXIST_ERR,drive_err
  1330.         moveq    #0,d0
  1331.         bra.b    .end
  1332. .okfilename    move.l    a3,d0
  1333.         move.l    d7,d1
  1334.         move.l    d6,d2
  1335.  
  1336. .end        movem.l    (a7)+,d3-d7/a0-a4
  1337.         rts
  1338.  
  1339. ;----------------------------------------------------------
  1340. ;-------------- test if disk was changed and reinit -------
  1341. ;-------------- partition structure -----------------------
  1342.  
  1343. ;-> a3=ptr on partition
  1344.  
  1345. test_change    movem.l    d0/a0-a3,-(a7)
  1346.         st    disk_op
  1347.         move.l    part_device(a3),a2
  1348.         moveq    #0,d0            ;test if changed cmd
  1349.         jsr    CHANGE_CMD(a2)
  1350.         tst.l    d0
  1351.         beq.b    .nochange
  1352.         bpl.b    .newdisk
  1353.         clr.l    part_filesystem(a3)    ;no disk
  1354.         bra.b    .end
  1355. .newdisk    lea.l    secbuf,a0
  1356.         clr.l    (a0)
  1357.         moveq    #0,d0
  1358.         jsr    READ_CMD(a2)        ;read boot-block
  1359.         move.l    secbuf,part_filesystem(a3)
  1360.         bra.b    .end
  1361. .nochange    tst.l    part_filesystem(a3)
  1362.         beq.b    .newdisk
  1363. .end        movem.l    (a7)+,d0/a0-a3
  1364.         rts
  1365.  
  1366. ;----------------------------------------------------------
  1367. ;-------------- copy name into file handle ----------------
  1368. ;-------------- convert it into BCPL ----------------------
  1369.  
  1370. ;-> d1=ptr on name ended by zero
  1371. ;-> a1=file_handle
  1372.  
  1373. copy_name    move.l    a2,-(a7)
  1374.         lea.l    file_name(a1),a2
  1375.         rept 8
  1376.         clr.l    (a2)+
  1377.         endr
  1378.         lea.l    file_name(a1),a2
  1379.         bsr    copy_name2
  1380.         move.l    (a7)+,a2
  1381.         rts
  1382.  
  1383. ;-> d1=ptr on name ended by zero
  1384. ;-> a2=dest address
  1385.  
  1386. copy_name2    movem.l    d0-d2/a0-a3,-(a7)
  1387.         lea.l    1(a2),a3
  1388.         move.l    d1,a0
  1389.         moveq    #30-1,d0        ;maxlen of filename
  1390.         moveq    #-1,d2
  1391. .copy        addq.w    #1,d2
  1392.         move.b    (a0)+,(a3)+
  1393.         dbeq    d0,.copy
  1394.         beq.b    .nomax
  1395.         moveq    #30,d2
  1396. .nomax        move.b    d2,(a2)            ;write filename len
  1397.         movem.l    (a7)+,d0-d2/a0-a3
  1398.         rts
  1399.  
  1400. ;----------------------------------------------------------
  1401.  
  1402. ;-> a1=file_handle
  1403. ;<- d0=hash val *4
  1404.  
  1405. calc_hash    movem.l    a0,-(a7)
  1406.         move.l    file_part(a1),a0
  1407.         move.b    part_filesystem+3(a0),d0    ;get DOSTYPE
  1408.         lea.l    file_name(a1),a0
  1409.         bsr.b    calc_hash2
  1410.         movem.l    (a7)+,a0
  1411.         rts
  1412.  
  1413. ;-> a0=ptr on BCPL name
  1414. ;-> d0=DOSTYPE 1=FFS, 3=INTL FFS, 5=DCFS
  1415. ;<- d0=hash val *4
  1416.  
  1417. calc_hash2    movem.l    d1-d3/a0-a1,-(a7)
  1418.         move.b    d0,d3            ;d3=DOSTYPE
  1419.         moveq    #0,d0
  1420.         move.b    (a0)+,d0        ;read len of name
  1421.  
  1422.         move.w    d0,d2
  1423.         subq.w    #1,d2
  1424.         move.w    d0,d1
  1425.         moveq    #0,d0
  1426. .loop2        mulu    #13,d1
  1427.         move.b    (a0)+,d0
  1428.         cmp.b    #3,d3            ;check DOSTYPE
  1429.         blt.b    .nointl
  1430.         cmp.b    #$f7,d0
  1431.         beq.b    .okintl
  1432.         bsr.b    intl_conv
  1433.         bra.b    .okintl
  1434. .nointl        bsr    upper_case
  1435. .okintl        add.w    d0,d1
  1436.         and.w    #$7ff,d1
  1437.         dbf    d2,.loop2
  1438.  
  1439.         divu    #72,d1
  1440.         swap    d1
  1441.         addq.w    #6,d1
  1442.         move.w    d1,d0
  1443.         lsl.w    #2,d0
  1444.         movem.l    (a7)+,d1-d3/a0-a1
  1445.         rts
  1446.  
  1447. ;-> d0=ascII char
  1448. intl_conv    movem.l    d1-d2,-(a7)
  1449.         move.b d0,d2
  1450.         move.l #"~`za",d1    ;$7e607a61
  1451.         bclr #7,d0
  1452.         beq.b .hashcv1
  1453.         swap d1
  1454. .hashcv1    cmp.b d1,d0
  1455.         blt.b .hashcv2
  1456.         lsr.l #8,d1
  1457.         cmp.b d1,d0
  1458.         bgt.b .hashcv2
  1459.         bclr #5,d2
  1460. .hashcv2    move.b d2,d0
  1461.         movem.l    (a7)+,d1-d2
  1462.         rts
  1463.  
  1464. ;----------------------------------------------------------
  1465.  
  1466. ;-> a1=file_handle
  1467. ;-> a0=ptr on BCPL name to compare
  1468. ;<- FLAGS =result 0=same -1=different
  1469.  
  1470. cmp_filename    movem.l    a1,-(a7)
  1471.         lea.l    file_name(a1),a1
  1472.         bsr.b    cmp_filename2
  1473.         movem.l    (a7)+,a1
  1474.         rts
  1475.  
  1476. ;-> a1=ptr on BCPL name1 to compare
  1477. ;-> a0=ptr on BCPL name2 to compare
  1478. ;<- FLAGS =result 0=same -1=different
  1479.  
  1480. cmp_filename2    movem.l    d0-d2/a0-a1,-(a7)
  1481.         move.b    (a1)+,d0
  1482.         cmp.b    (a0)+,d0
  1483.         bne.b    .err
  1484.         moveq    #0,d1
  1485.         move.b    d0,d1
  1486.         bra.b    .godbf
  1487. .loop        move.b    (a1)+,d0
  1488.         bsr    upper_case
  1489.         move.b    d0,d2
  1490.         move.b    (a0)+,d0
  1491.         bsr    upper_case
  1492.         cmp.b    d0,d2
  1493.         bne.b    .err
  1494. .godbf        dbf    d1,.loop
  1495.         moveq    #0,d0
  1496.         bra.b    .ok
  1497. .err        moveq    #-1,d0
  1498. .ok        movem.l    (a7)+,d0-d2/a0-a1
  1499.         rts
  1500.  
  1501. ;---------------------------------------------------------------
  1502. ;-------------- find a free block in the bitmap and set it -----
  1503.  
  1504. ;-> a1=ptr on file_handle
  1505. ;<- d0=free block no. -1=error
  1506.  
  1507. alloc_block    movem.l    d1-d7/a0-a4,-(a7)
  1508.         move.l    file_part(a1),a3
  1509.         move.l    part_device(a3),a2
  1510.  
  1511.         cmp.l    bitmap_part,a3
  1512.         beq.w    .okloaded
  1513.  
  1514. .search        bsr    update_bitmap
  1515.         move.l    a3,bitmap_part
  1516.         move.l    part_nbsec(a3),d0
  1517.         lsr.l    #1,d0            ;ROOT block
  1518.         lea.l    secbuf,a0
  1519.         bsr    read_fbuffer        ;read ROOT block
  1520.  
  1521.         move.w    #79*4,d4        ;start of bitmap_block table
  1522.         move.w    #104*4,d5        ;end of table
  1523.         move.l    #2,bitmap_offset
  1524.  
  1525. .next        bsr    update_bitmap
  1526.         lea.l    secbuf,a0
  1527.         move.l    (a0,d4.w),d0        ;get bitmap block
  1528.         move.l    d0,bitmap_no
  1529.         lea.l    bitmap,a0
  1530.         bsr    read_fbuffer        ;read bitmap block
  1531.  
  1532.         bsr    alloc_block2
  1533.         tst.l    d0
  1534.         bmi.b    .diskfull
  1535.         bne.b    .end
  1536.         add.l    #127*32,bitmap_offset
  1537.         addq.w    #4,d4            ;next block in bitmap list
  1538.         cmp.w    d5,d4            ;max val reached ?
  1539.         bne.b    .next
  1540.         lea.l    secbuf,a0
  1541.         move.l    (a0,d5.w),d0        ;get next bitmap list no
  1542.         bsr    read_fbuffer
  1543.         move.w    #127*4,d5
  1544.         moveq    #0,d4
  1545.         bra.b    .next
  1546.  
  1547.  
  1548. .okloaded    bsr    alloc_block2
  1549.         tst.l    d0            ;found a free block ?
  1550.         bmi.b    .diskfull
  1551.         beq.w    .search
  1552. .end
  1553. .diskfull    tst.l    d0
  1554.         movem.l    (a7)+,d1-d7/a0-a4
  1555.         rts
  1556.  
  1557. ;-------------- find a free block in the actual bitmap block --------
  1558. ;-------------- (called by alloc_block only) ------------------------
  1559.  
  1560. ;-> a3=ptr on partition
  1561. ;<- d0=no of free block, 0=no free block in bitmap block, -1=disk full
  1562.  
  1563. alloc_block2    movem.l    d1-d3/a0,-(a7)
  1564.         lea.l    bitmap+4,a0
  1565.         move.l    bitmap_offset,d0
  1566.         move.l    part_nbsec(a3),d3    ;max limit
  1567.  
  1568. .seek2        move.l    (a0)+,d1
  1569.         bne.b    .deeper
  1570.         moveq    #32,d1
  1571.         add.l    d1,d0
  1572.         cmp.l    d3,d0
  1573.         bge.b    .full
  1574.         bra.b    .skip
  1575. .deeper        moveq    #32-1,d2
  1576. .seek        lsr.l    #1,d1
  1577.         bcs.b    .found
  1578.         addq.l    #1,d0
  1579.         cmp.l    d3,d0
  1580.         bge.b    .full
  1581.         dbf    d2,.seek
  1582. .skip        cmp.l    #bitmap+512,a0
  1583.         bne.b    .seek2
  1584.         moveq    #0,d0            ;end of block reached
  1585.         bra.b    .end
  1586.  
  1587. .full        moveq    #-1,d0
  1588.         bra.b    .end
  1589.  
  1590. .found        move.l    d0,d1
  1591.         sub.l    bitmap_offset,d1
  1592.         move.l    d1,d2
  1593.         lsr.l    #5,d2
  1594.         lea.l    bitmap+4,a0
  1595.         lsl.l    #2,d2
  1596.         move.l    (a0,d2.l),d3
  1597.         and.l    #$1f,d1
  1598.         bclr    d1,d3            ;alloc block in bitmap
  1599.         move.l    d3,(a0,d2.l)
  1600.         st    bitmap_modified
  1601.         tst.l    d0
  1602.  
  1603. .end        movem.l    (a7)+,d1-d3/a0
  1604.         rts
  1605.  
  1606. ;---------------------------------------------------------------
  1607. ;-------------- free a block in the bitmap ---------------------
  1608.  
  1609. ;-> d0=no of block to free
  1610. ;-> a1=ptr on file_handle
  1611.  
  1612. free_block    movem.l    d0-a4,-(a7)
  1613.         move.l    file_part(a1),a3
  1614.         move.l    part_device(a3),a2
  1615.         move.l    d0,d7
  1616.  
  1617.         cmp.l    bitmap_part,a3
  1618.         bne.b    .load
  1619.  
  1620.         move.l    d0,d7
  1621.         move.l    bitmap_offset,d0
  1622.         cmp.l    d0,d7            ;is this block in the
  1623.         blt.b    .load            ;actual bitmap block
  1624.         add.l    #127*32,d0
  1625.         cmp.l    d0,d7
  1626.         bge.b    .load
  1627.  
  1628. .free        move.l    d7,d1
  1629.         sub.l    bitmap_offset,d1
  1630.         move.l    d1,d2
  1631.         lsr.l    #5,d2
  1632.         lea.l    bitmap+4,a0
  1633.         lsl.l    #2,d2
  1634.         move.l    (a0,d2.l),d3
  1635.         and.l    #$1f,d1
  1636.         bset    d1,d3            ;free block in bitmap
  1637.         move.l    d3,(a0,d2.l)
  1638.         bra.w    .end
  1639.  
  1640. .load        bsr    update_bitmap
  1641.         move.l    d7,d6
  1642.         divu    #127*32,d6        ;d6=no of block to search
  1643.         ext.l    d6
  1644.  
  1645.         move.l    a3,bitmap_part
  1646.         move.l    part_nbsec(a3),d0
  1647.         lsr.l    #1,d0            ;ROOT block
  1648.         lea.l    secbuf,a0
  1649.         bsr    read_fbuffer        ;read ROOT block
  1650.         bsr    test_sum
  1651.         bne.b    .error
  1652.  
  1653.         move.w    #79*4,d4        ;start of bitmap_block table
  1654.         move.w    #104*4,d5        ;end of table
  1655.         move.l    #2,bitmap_offset
  1656.  
  1657. .nomax        tst.l    d6
  1658.         beq.b    .found
  1659.         add.l    #32*127,bitmap_offset
  1660.         subq.l    #1,d6
  1661.         addq.w    #4,d4
  1662.         cmp.w    d4,d5
  1663.         bne.b    .nomax
  1664.         lea.l    secbuf,a0
  1665.         move.l    (a0,d4.w),d0
  1666.         bsr    read_fbuffer        ;read the bitmap block table
  1667.         moveq    #0,d4
  1668.         move.w    #127*4,d5
  1669.         bra.b    .nomax
  1670.  
  1671. .found        lea.l    secbuf,a0
  1672.         move.l    (a0,d4.w),d0
  1673.         move.l    d0,bitmap_no
  1674.         lea.l    bitmap,a0
  1675.         bsr    read_fbuffer        ;read the bitmap block
  1676.         bsr    test_sum
  1677.         bne.b    .error
  1678.         bra.w    .free
  1679.  
  1680. .end        st    bitmap_modified
  1681.  
  1682. .error        movem.l    (a7)+,d0-a4
  1683.         rts
  1684.  
  1685. ;----------------------------------------------------------
  1686. ;-------------- write back the bitmap to disk -------------
  1687.  
  1688. update_bitmap    movem.l    d0/a0-a3,-(a7)
  1689.         tst.b    bitmap_modified
  1690.         beq.b    .nomodif
  1691.         sf    bitmap_modified
  1692.         move.l    bitmap_part,a3
  1693.         move.l    part_device(a3),a2
  1694.         lea.l    bitmap,a0
  1695.         bsr    calc_bitmapsum
  1696.         move.l    bitmap_no,d0
  1697.         bsr    write_fbuffer
  1698. .nomodif    movem.l    (a7)+,d0/a0-a3
  1699.         rts
  1700.  
  1701. ;----------------------------------------------------------
  1702. ;calculate a block checksum and write it in the block
  1703. ;-> a0=ptr on block
  1704.  
  1705. calc_sum    movem.l    d0-d1/a0-a1,-(a7)
  1706.         move.l    a0,a1
  1707.         clr.l    5*4(a0)            ;clear sum
  1708.         moveq    #0,d1
  1709.         moveq    #512/4-1,d0
  1710. .sum        add.l    (a0)+,d1
  1711.         dbf    d0,.sum
  1712.         neg.l    d1
  1713.         move.l    d1,5*4(a1)
  1714.         movem.l    (a7)+,d0-d1/a0-a1
  1715.         rts
  1716.  
  1717. ;----------------------------------------------------------
  1718. ;-------------- calcualte bitmap checksum and set it ------
  1719.  
  1720. ;-> a0=ptr on bitmap block
  1721.  
  1722. calc_bitmapsum    movem.l    d0-d1/a0-a1,-(a7)
  1723.         move.l    a0,a1
  1724.         clr.l    (a0)            ;clear sum
  1725.         moveq    #0,d1
  1726.         moveq    #512/4-1,d0
  1727. .sum        add.l    (a0)+,d1
  1728.         dbf    d0,.sum
  1729.         neg.l    d1
  1730.         move.l    d1,(a1)
  1731.         movem.l    (a7)+,d0-d1/a0-a1
  1732.         rts
  1733.  
  1734. ;----------------------------------------------------------
  1735. ;-------------- test the checksum of a block --------------
  1736.  
  1737. ;-> a0=ptr on block to test
  1738. ;<- FLAGS 0=sum ok -1=bad checksum
  1739.  
  1740. test_sum:    movem.l    d0-d1/a0,-(a7)
  1741.         moveq    #0,d0
  1742.         moveq    #512/16-1,d1
  1743. .sum        add.l    (a0)+,d0
  1744.         add.l    (a0)+,d0
  1745.         add.l    (a0)+,d0
  1746.         add.l    (a0)+,d0
  1747.         dbf    d1,.sum
  1748.         tst.l    d0
  1749.         beq.b    .ok
  1750.         move.w    #BADCHECKSUM_ERR,drive_err
  1751.         moveq    #-1,d0
  1752. .ok        movem.l    (a7)+,d0-d1/a0
  1753.         rts
  1754.  
  1755.  
  1756.         cnop 0,4
  1757.  
  1758. file_handle1    dc.l 0            ;part
  1759.         dc.l 0            ;parent
  1760.         dc.l 0            ;header
  1761.         dc.l 0            ;extension
  1762.         dc.l 0            ;extension pos
  1763.         dc.l 0            ;filesize
  1764.         dc.l 0            ;seek pos
  1765.         dcb.b 32,0        ;name
  1766.         dc.b 0            ;written flag
  1767.         dc.b 0            ;dir
  1768.         cnop 0,4
  1769.  
  1770. file_handle2    dc.l 0            ;part
  1771.         dc.l 0            ;parent
  1772.         dc.l 0            ;header
  1773.         dc.l 0            ;extension
  1774.         dc.l 0            ;extension pos
  1775.         dc.l 0            ;filesize
  1776.         dc.l 0            ;seek pos
  1777.         dcb.b 32,0        ;name
  1778.         dc.b 0            ;written flag
  1779.         dc.b 0            ;dir
  1780.         cnop 0,4
  1781.  
  1782. current_dir    dc.l floppy0        ;ptr on partition
  1783.         dc.l 880        ;ptr on dir key
  1784.  
  1785. part_nametemp    dcb.b 32,0
  1786.  
  1787.         cnop 0,4
  1788.  
  1789. extension    dcb.b 512,0        ;buffers
  1790. secbuf        dcb.b 512,0        ;used for
  1791. bitmap        dcb.b 512,0        ;filesystem
  1792.  
  1793. bitmap_no    dc.l 0            ;no of bitmap sector in bitmap buffer
  1794. bitmap_part    dc.l 0            ;ptr on partition of bitmap buffer
  1795. bitmap_offset    dc.l 0            ;no of the first block of the bitmap
  1796. bitmap_modified    dc.b 0            ;0=no modif. -1=modified
  1797.         cnop 0,4
  1798.  
  1799.